import config from './config.js'
import util from '../util.js'

// 小程序中实现token过期重新登录再重新请求业务接口
// http://events.jianshu.io/p/c1a257b283b1

/**
 * 请求数据处理
 * @param string url 请求地址
 * @param string method 请求方式
 *  GET or POST
 * @param {*} postData 请求参数
 * @param bool isDelay 是否延迟显示loading  false
 * @param bool isForm 数据格式 
 *  true: 'application/x-www-form-urlencoded'
 *  false:'application/json'
 * @param bool hideLoading 是否隐藏loading 获取数据之前的等待 false
 *  true: 隐藏
 *  false:显示
 */

// 请求格式
// this.tui.request({
// 	url: '/czb/system_config/getConfigArticleDetails',
// 	method: 'POST',
// 	data: data
// }, false, true, false).then((res) => {
// })

// 是否正在刷新token的标记
let isRefreshing = false
//重试请求队列
let requestList = []


const request = {
	delayed: null, //定时器

	request: function (opts, isDelay, isForm, hideLoading, isShowMsg) {
		//接口请求
		let loadding = false;
		request.delayed && uni.hideLoading();
		// 关闭定时器
		clearTimeout(request.delayed);
		request.delayed = null;
		if (!hideLoading) {
			request.delayed = setTimeout(() => {
				uni.showLoading({
					mask: true,
					title: '请稍候...',
					success(res) {
						loadding = true
					}
				})
			}, isDelay ? 1000 : 0)
		}

		return new Promise((resolve, reject) => {

			Send(opts).then(async res => {
				let resdata = res.data;
				if (res.statusCode == 200) { //成功
					if (resdata.Success) {
						resolve(resdata)
					} else {
						if (!isShowMsg) {
							util.toast(resdata.Message)
						}
						resolve(resdata)
					}
				} else if (res.statusCode == 401) { //401  登录失效 超时
					const reSend = () => {
						Send(opts).then(reRes => {
							resdata = reRes.data
							if (reRes.statusCode == 200) { //成功
								if (!resdata.Success && !isShowMsg) {
									util.toast(resdata.Message)
								}
							} else if (reRes.statusCode == 401) {
								uni.setStorageSync("access_token", "");
								uni.navigateTo({
									url: "/pages/Login/login"
								})
							}
							resolve(resdata)
						}).catch((reRes) => {
							reject(reRes)
						});
					}

					if (!isRefreshing) {
						isRefreshing = true
						//刷新 token 
						console.log("登录失效/超时，刷新token");
						const isRefreshSuccess = await Refreshtoken();
						if (isRefreshSuccess) {
							//刷新成功，则回放队列的请求 + 当前请求
							reSend();
							requestList.forEach(cb => cb())
						} else {
							//刷新失败，跳转登录
							uni.setStorageSync("access_token", "");
							uni.reLaunch({
								url: "/pages/Login/login"
							})
							resolve(resdata)
						}
						//清空重试队列
						requestList = []
						isRefreshing = false
					} else {
						// 添加到队列，等待刷新获取到新的令牌
						requestList.push(reSend)
					}
				} else {
					util.toast(resdata.Message)
					resolve(resdata)
				}

				clearTimeout(request.delayed)
				request.delayed = null;
				if (loadding && !hideLoading) {
					uni.hideLoading()
				}
			})
				.catch(res => {
					clearTimeout(request.delayed)
					request.delayed = null;
					util.toast("网络不给力，请稍后再试~")
					reject(res)
				}).finally(() => {
					setTimeout(() => {
						uni.hideLoading()
					}, 100)
				})
		})
	}
}

function Send(opts) {

	const token = uni.getStorageSync("access_token");
	const currentCorp = uni.getStorageSync('dianjiqiye') || {}
	const headers = {
		'content-type': 'application/json'
	};
	if (token) {
		headers["Authorization"] = `Bearer ${token.access_token}`
	}
	if (currentCorp) {
		headers['corp'] = `${currentCorp.Id}`
	}
	if (!new RegExp(/(http|https|ftp):\/\/\S*/).test(opts.url)) {
		opts.url = config.domain.baseUrl + opts.url
	}
	return new Promise((resolve, reject) => {
		uni.request({
			url: opts.url,
			data: opts.data,
			header: headers,
			method: opts.method || 'POST',
			dataType: 'json',
			success: (res) => {
				resolve(res);
			},
			// 接口调用失败的回调函数
			fail: (res) => {
				reject(res)
			},
			complete: () => {
				//console.log(`request api ${opts.url}`, headers)
			}
		})
	});
}

// 刷新token
function Refreshtoken() {
	const token = uni.getStorageSync("access_token") || {};
	const expires_at = token.expires_at || 0;
	if (Date.now() < expires_at) {
		return Promise.resolve(true);
	}
	const refresh_token = token?.refresh_token;
	if (!refresh_token || refresh_token.length == 0) {
		return Promise.resolve(false);
	}
	return new Promise((resolve, reject) => {
		uni.request({
			url: config.domain.loginurl,
			method: 'POST',
			header: {
				'content-type': "application/x-www-form-urlencoded"
			},
			data: {
				client_id: "hui_app",
				grant_type: "refresh_token",
				refresh_token: refresh_token
			},
			// sslVerify: false,
			success: res => {
				if (res.statusCode === 200) {
					//保存 access_token
					const token = res.data;
					const expires_at = Math.floor(token.expires_in) + Math.floor(Date.now() / 1000)
					token.expires_at = expires_at;
					uni.setStorageSync("access_token", token);
					resolve(true);
				} else {
					resolve(false);
				}
			},
			fail(e) {
				util.toast("网络不给力，请稍后再试~")
				resolve(false);
			}
		})
	})
}

export default request